package com.you.weixinpay.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.you.weixinpay.properties.WeChatProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;

@Slf4j
@Configuration
@RequiredArgsConstructor
public class WeChatPayConfig {

    private final WeChatProperties weChatProperties;

    private PrivateKey loadPrivateKey() {
        try (FileInputStream fis = new FileInputStream(weChatProperties.getPrivateKeyFilePath())) {
            return PemUtil.loadPrivateKey(fis);
        } catch (Exception e) {
            log.error("加载商户私钥失败", e);
            throw new RuntimeException("加载商户私钥失败", e);
        }
    }

    /**
     * 获取HttpClient，无需进行应答签名验证，跳过验签的流程
     */
    @Bean("httpClient")
    public CloseableHttpClient wechatPayHttpClient() throws Exception {
        // 加载商户私钥
        PrivateKey merchantPrivateKey = loadPrivateKey();
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(
                weChatProperties.getMchid(),
                new WechatPay2Credentials(weChatProperties.getMchid(), new PrivateKeySigner(weChatProperties.getMchSerialNo(), merchantPrivateKey)),
                weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8)
        );
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(weChatProperties.getMchid());

        log.info("==  【微信】【进行】应答签名验证，执行验签的流程  END ==");

        // 初始化httpClient
        return WechatPayHttpClientBuilder.create()
                .withMerchant(weChatProperties.getMchid(), weChatProperties.getMchSerialNo(), merchantPrivateKey)
                .withValidator(new WechatPay2Validator(verifier))
                .build();
    }

    /**
     * 获取HttpClient，无需进行应答签名验证，跳过验签的流程
     */
    @Bean("wxPayNoSignClient")
    public CloseableHttpClient wxPayNoSignClient() throws Exception {
        // 加载商户私钥
        PrivateKey merchantPrivateKey = loadPrivateKey();
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(
                weChatProperties.getMchid(),
                new WechatPay2Credentials(weChatProperties.getMchid(), new PrivateKeySigner(weChatProperties.getMchSerialNo(), merchantPrivateKey)),
                weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8)
        );
        // 从证书管理器中获取verifier
        Verifier verifier = certificatesManager.getVerifier(weChatProperties.getMchid());

        log.info("== 【微信】 【无需进行】应答签名验证，跳过验签的流程  END ==");

        // 初始化httpClient
        return WechatPayHttpClientBuilder.create()
                .withMerchant(weChatProperties.getMchid(), weChatProperties.getMchSerialNo(), merchantPrivateKey)
                .withValidator(response -> true)
                .build();
    }

    /**
     * 获取签名验证器
     */
    @Bean
    public Verifier verifier() throws Exception {
        log.info("获取【微信】签名验证器");
        // 加载商户私钥
        PrivateKey merchantPrivateKey = loadPrivateKey();
        // 获取证书管理器实例
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        certificatesManager.putMerchant(
                weChatProperties.getMchid(),
                new WechatPay2Credentials(weChatProperties.getMchid(),
                        new PrivateKeySigner(weChatProperties.getMchSerialNo(), merchantPrivateKey)),
                weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8)
        );

        return certificatesManager.getVerifier(weChatProperties.getMchid());
    }


}